package cn.coufran.springboot.starter.auth;

/**
 * 配合{@link AuthUserManager}使用，AuthUser只实现基础的数据保存，所有上下文操作交由{@link AuthUserManager}处理。
 * @author Coufran
 * @version 1.0.0
 * @since 1.0.0
 */
public abstract class AbstractAuthUser<D> implements AuthUser<D> {
    /** 持有的权限上下文 */
    private AuthUserManager authUserManager;
    /** 是否通过认证 */
    private boolean authenticated;
    /** 数据 */
    private D data;

    /**
     * 构造匿名用户
     * @param authUserManager 权限上下文
     */
    public AbstractAuthUser(AuthUserManager authUserManager) {
        this(authUserManager, false, null);
    }

    /**
     * 构造认证用户
     * @param authUserManager 权限上下文
     * @param data 数据
     */
    public AbstractAuthUser(AuthUserManager authUserManager, D data) {
        this(authUserManager, true, data);
    }

    /**
     * 构造用户
     * @param authUserManager 全限上下文
     * @param authenticated 是否通过认证
     * @param data 数据
     */
    public AbstractAuthUser(AuthUserManager authUserManager, boolean authenticated, D data) {
        this.authUserManager = authUserManager;
        this.authenticated = authenticated;
        this.data = data;
    }

    /**
     * 是否已认证
     * @return 已认证返回true
     */
    public boolean isAuthenticated() {
        return authenticated;
    }

    /**
     * 获取基础数据
     * @return 基础数据
     */
    public D getData() {
        return data;
    }

    /**
     * 登录并设置基础数据
     * @param data 基础数据
     * @return 此次登录对应的Token组
     */
    public Certificate login(D data) {
        Certificate certificate = authUserManager.acceptLogin(this, data);
        this.authenticated = true;
        this.data = data;
        return certificate;
    }

    /**
     * 刷新登录状态
     * @return 新权限证书
     */
    @Override
    public Certificate refresh() {
        return authUserManager.acceptRefresh(this);
    }

    /**
     * 登出
     */
    public void logout() {
        authUserManager.acceptLogout(this);
        this.authenticated = false;
        this.data = null;
    }
}
